package com.sky.tool.maven.plugins

import org.apache.maven.plugins.annotations.LifecyclePhase
import org.apache.maven.plugins.annotations.Mojo
import org.codehaus.plexus.util.FileUtils
import org.codehaus.plexus.util.StringUtils
import org.dom4j.Document
import org.dom4j.Element
import org.dom4j.io.SAXReader
import org.dom4j.io.XMLWriter

import java.nio.charset.StandardCharsets

@Mojo(defaultPhase = LifecyclePhase.PACKAGE, name = "make-win-service")
public class WindowsServiceMojo extends AbstractServiceMojo {
    private static final String EXE_FILE_URL = "/windows/service.exe";
    private static final String XML_FILE_URL = "/windows/service.xml";
    private static final String CONFIG_FILE_URL = "/windows/service.exe.config";
    private static final String README_FILE_URL = "/windows/readme.txt";

    @Override
    public void generate() {
        try {
            /*创建文件夹*/
            File distDir = new File(targetDir, "/windows");
            if (!distDir.exists()) {
                distDir.mkdirs();
            }
            File logDir = new File(distDir, File.separator + "logs");
            FileUtils.mkdir(logDir.getPath());
            getLog().info("创建输出文件目录:" + targetDir);
            /*下载文件*/
            FileUtils.copyURLToFile(getClass().getResource(README_FILE_URL), new File(distDir, File.separator + "readme.txt"));
            FileUtils.copyURLToFile(getClass().getResource(XML_FILE_URL), new File(distDir, File.separator + appName + ".xml"));
            FileUtils.copyURLToFile(getClass().getResource(EXE_FILE_URL), new File(distDir, File.separator + appName + ".exe"));
            FileUtils.copyURLToFile(getClass().getResource(CONFIG_FILE_URL), new File(distDir, File.separator + appName + ".exe.config"));
            getLog().info("生成服务配置文件");
            convert(new File(distDir.getPath() + File.separator + appName + ".xml"));
            getLog().info("生成批处理文件");
            createBat(distDir, "install.bat", "install");
            createBat(distDir, "uninstall.bat", "uninstall");
            createBat(distDir, "start.bat", "start");
            createBat(distDir, "stop.bat", "stop");
            createBat(distDir, "restart.bat", "restart");

        } catch (Exception e) {
            getLog().error("制作Windows Service 失败：", e);
        }
    }


    /**
     * 属性转化
     *
     * @param xmlFile xml文件
     */
    private void convert(File xmlFile) {
        SAXReader reader = new SAXReader();
        try {
            Document document = reader.read(xmlFile);
            Element root = document.getRootElement();
            root.element("id").setText(appId);
            root.element("name").setText(appName);
            root.element("description").setText(description);
            String vm_options = StringUtils.isEmpty(vmOptions) ? " " : " " + vmOptions + " ";
            String program_arguments = StringUtils.isEmpty(programArguments) ? "" : " " + programArguments;
            root.element("arguments").setText(vm_options + "-jar " + runJarName + program_arguments);
            saveXML(document, xmlFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 保存 XML 文件
     *
     * @param document 文档
     * @param xmlFile xml文件
     */
    private void saveXML(Document document, File xmlFile) {
        try {
            XMLWriter writer = new XMLWriter(new OutputStreamWriter(new FileOutputStream(xmlFile), StandardCharsets.UTF_8));
            writer.write(document);
            writer.flush();
            writer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * @param outDri 输出目录
     * @param fileName 文件名
     * @param text 命令文本
     */
    private void createBat(File outDri, String fileName, String text) {
        if (!outDri.exists()) {
            FileUtils.mkdir(outDri.getPath())
        }
        new File(outDri, fileName) <<
                """
@echo off
%1 mshta vbscript:CreateObject("Shell.Application").ShellExecute("cmd.exe","/c %~s0 ::","","runas",1)(window.close)&&exit
%~dp0${appName}.exe   ${text} 
echo The  ${appName}  service current state:
%~dp0${appName}.exe status
pause
                    """

    }
}
